iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
Software Development

Rust Web API 從零開始系列 第 19

Day19 - 建立自動化流程

  • 分享至 

  • xImage
  •  

昨天手動把專案部屬好了,接下來我想要幫專案加上自動化流程,讓每次的異動都能跑過測試並佈署到fly.io,因為專案放在github上,理所當然的選擇了github action作為CICD工具,預計每次都會執行下面的pipline:
https://ithelp.ithome.com.tw/upload/images/20230915/20148594I0fBo3QQuN.png

目前最容易找到的action-rs已經不再維護,不建議使用,但是Github提供的actions runner本身就安裝了rust工具鏈,如果真的有需求的話推薦使用這個

詳細的pipline可以參考repo中的設定,以下只針對其中幾個步驟進行說明

unit test

  unit-test: 
    name: run unit tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/cache@v3
        with:
          path: |
            target
          key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
      - name: run test
        run: cargo test --verbose

rust的編譯時須檢查相關依賴套件是否已經編譯過,如果沒有的話需要重新下載一次,這個步驟在Github上極為緩慢,所以我們可以使用Cache的機制加速。編譯時期的依賴套件會放在target資料夾中,這也就是我們快取的目標。Cargo.lock是用來鎖定套件版本依賴的文件,每次編譯成功會鎖住當時的依賴。這時就會有一個問題,Cargo.lock檔案是否要被加入gitignore中,這點要依專案性質而定,如果是應用端的專案會不建議加入,如果是單純的函式庫,編譯時會取決於使用函式庫的應用端,就建議加入gitignore中。

prepare database

  prepare-test-db:
    name: prepare test database
    runs-on: ubuntu-latest
    env:
      FLY_API_TOKEN: ${{ secrets.FLY_POSTGRES_TOKEN }}
      DATABASE_URL: ${{ secrets.DATABASE_URL_INTERGRATION_TEST }}
    steps:
      - uses: actions/checkout@v3
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - uses: actions/cache@v3
        with:
          path: |
            migration/target
          key: ${{ runner.os }}-sea-orm-migration-${{ hashFiles('**migration/Cargo.lock') }}
      - name: set fly-postgres proxy
        run: nohup flyctl proxy 5432 -a marvinhsu-postgres &
      - name: reset test database
        run: |
          cd migration
          cargo run fresh

因為使用seaORM的工具進行資料庫版本管理,所以就可以將遷移專案用來準備整合測試用的資料庫。因為這時候測試是使用github action的runner進行,為了能夠連線到資料庫就需要使用fly.io的代理機制建立連線,最後使用cargo run fresh,就相當於在本機使用sea-orm-cli migrate fresh

pytest

因為有撰寫整合測試,自然要通過才能進行部屬:

  pytest:
    name: run intregation tests
    needs: [build,prepare-test-db]
    runs-on: ubuntu-latest
    env:
      FLY_API_TOKEN: ${{ secrets.FLY_POSTGRES_TOKEN }}
      DATABASE_URL: ${{ secrets.DATABASE_URL_INTERGRATION_TEST }}
    steps:
      - uses: actions/checkout@v3
      - name: Install Poetry
        uses: snok/install-poetry@v1
      - uses: actions/cache@v3
        with:
          path: ~/.cache/pypoetry
          key: ${{ runner.os }}-poetry-${{ hashFiles('**/pyproject.toml') }}
      - name: Install pytest and requests
        run: poetry install
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - uses: actions/download-artifact@v3
        with:
          name: zero_to_production.tar
      - name: load docker image
        run: docker load -i zero_to_production.tar
      - name: set fly-postgres proxy
        run: nohup flyctl proxy 5432 -a marvinhsu-postgres &
      - name: run image
        run: |
          docker run \
          -e APP__ENVIRONMENT=test \
          -e APP__DATABASE__PASSWORD=${{ secrets.DATABASE_PASSWORD_INTERGRATION_TEST }} \
          --network host \
          -d zero_to_production
      - name: Run tests
        run: poetry run pytest

整合測試的步驟較為複雜,因為使用poetry管理環境,官方的image並不支援就需要自行安裝,另外要對測試專安的相依性進行還原。為了減少建置時間將docker image在第一步的時候就先輸出成.tar,所以在進行整合測試時要先載入。這邊有個小技巧,因為測試用的資料庫需要透過fly的代理才能夠連線,而專案又被包在docker中,所以在運行容器的時候需要對網路做一些調整才能使用,這邊為了求方便,而且只是測試使用,所以我直接開啟了host network模式來共享主機的5432port。

接下來遷移production環境資料庫與佈署的部份與前面的步驟大同小異,就不贅述了。


上一篇
Day18 - 佈署到Fly.io
下一篇
Day20 - 使用reqwest串接寄信服務
系列文
Rust Web API 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言